#include "stdafx.h"
#include "Fakes/FakeD3D11Device.h"
#include "Fakes/FakeD3D11DepthStencilState.h"

DESCRIPTION_11_TEST_SUITE(DepthStencilDescription)

BOOST_FIXTURE_TEST_CASE(Default, TestDepthStencilDescription)
{
	BOOST_REQUIRE_EQUAL(TRUE, m_desc.DepthEnable);
    BOOST_REQUIRE_EQUAL(D3D11_DEPTH_WRITE_MASK_ALL, m_desc.DepthWriteMask);
    BOOST_REQUIRE_EQUAL(D3D11_COMPARISON_LESS, m_desc.DepthFunc);
    BOOST_REQUIRE_EQUAL(FALSE, m_desc.StencilEnable);
    BOOST_REQUIRE_EQUAL(D3D11_DEFAULT_STENCIL_READ_MASK, m_desc.StencilReadMask);
    BOOST_REQUIRE_EQUAL(D3D11_DEFAULT_STENCIL_WRITE_MASK, m_desc.StencilWriteMask);
    BOOST_REQUIRE_EQUAL(D3D11_STENCIL_OP_KEEP, m_desc.FrontFace.StencilFailOp);
    BOOST_REQUIRE_EQUAL(D3D11_STENCIL_OP_KEEP, m_desc.FrontFace.StencilDepthFailOp);
    BOOST_REQUIRE_EQUAL(D3D11_STENCIL_OP_KEEP, m_desc.FrontFace.StencilPassOp);
    BOOST_REQUIRE_EQUAL(D3D11_COMPARISON_ALWAYS, m_desc.FrontFace.StencilFunc);
	BOOST_REQUIRE_EQUAL(D3D11_STENCIL_OP_KEEP, m_desc.BackFace.StencilFailOp);
    BOOST_REQUIRE_EQUAL(D3D11_STENCIL_OP_KEEP, m_desc.BackFace.StencilDepthFailOp);
    BOOST_REQUIRE_EQUAL(D3D11_STENCIL_OP_KEEP, m_desc.BackFace.StencilPassOp);
    BOOST_REQUIRE_EQUAL(D3D11_COMPARISON_ALWAYS, m_desc.BackFace.StencilFunc);
}

#define DEPTH_STENCIL_DESCRIPTION_TEST_CASE(type_, name_, value_) \
	DESCRIPTION_11_SETTER_TEST_CASE(type_, name_, value_, DepthStencilDescription)

DEPTH_STENCIL_DESCRIPTION_TEST_CASE(BOOL, DepthEnable, FALSE)
DEPTH_STENCIL_DESCRIPTION_TEST_CASE(D3D11_DEPTH_WRITE_MASK, DepthWriteMask, D3D11_DEPTH_WRITE_MASK_ZERO)
DEPTH_STENCIL_DESCRIPTION_TEST_CASE(D3D11_COMPARISON_FUNC, DepthFunc, D3D11_COMPARISON_NEVER)
DEPTH_STENCIL_DESCRIPTION_TEST_CASE(BOOL, StencilEnable, TRUE)
DEPTH_STENCIL_DESCRIPTION_TEST_CASE(UINT8, StencilReadMask, 0)

BOOST_FIXTURE_TEST_CASE(FrontFace, TestDepthStencilDescription)
{
	D3D11_DEPTH_STENCILOP_DESC const op =
	{ D3D11_STENCIL_OP_REPLACE, D3D11_STENCIL_OP_REPLACE, D3D11_STENCIL_OP_REPLACE, D3D11_COMPARISON_NEVER };
	D3D11_DEPTH_STENCILOP_DESC front = m_desc.FrontFace_(op).FrontFace;
	BOOST_REQUIRE_EQUAL(op.StencilDepthFailOp, front.StencilDepthFailOp);
	BOOST_REQUIRE_EQUAL(op.StencilFailOp, front.StencilFailOp);
	BOOST_REQUIRE_EQUAL(op.StencilFunc, front.StencilFunc);
	BOOST_REQUIRE_EQUAL(op.StencilPassOp, front.StencilPassOp);
}

BOOST_FIXTURE_TEST_CASE(BackFace, TestDepthStencilDescription)
{
	D3D11_DEPTH_STENCILOP_DESC const op =
	{ D3D11_STENCIL_OP_REPLACE, D3D11_STENCIL_OP_REPLACE, D3D11_STENCIL_OP_REPLACE, D3D11_COMPARISON_NEVER };
	D3D11_DEPTH_STENCILOP_DESC back = m_desc.BackFace_(op).BackFace;
	BOOST_REQUIRE_EQUAL(op.StencilDepthFailOp, back.StencilDepthFailOp);
	BOOST_REQUIRE_EQUAL(op.StencilFailOp, back.StencilFailOp);
	BOOST_REQUIRE_EQUAL(op.StencilFunc, back.StencilFunc);
	BOOST_REQUIRE_EQUAL(op.StencilPassOp, back.StencilPassOp);
}

#define DEPTH_STENCIL_DESCRIPTION_FIXTURE_TEST_CASE(methodName_, type_, value_, fieldName_) \
	DESCRIPTION_11_SETTER_FIXTURE_TEST_CASE(methodName_, DepthStencilDescription, \
		type_, value_, fieldName_)

#define FRONT_DEPTH_STENCIL_DESCRIPTION_TEST_CASE(type_, fieldName_, value_) \
	DEPTH_STENCIL_DESCRIPTION_FIXTURE_TEST_CASE(Front##fieldName_##_, type_, value_, FrontFace.fieldName_)
FRONT_DEPTH_STENCIL_DESCRIPTION_TEST_CASE(D3D11_STENCIL_OP, StencilFailOp, D3D11_STENCIL_OP_REPLACE)
FRONT_DEPTH_STENCIL_DESCRIPTION_TEST_CASE(D3D11_STENCIL_OP, StencilDepthFailOp, D3D11_STENCIL_OP_REPLACE)
FRONT_DEPTH_STENCIL_DESCRIPTION_TEST_CASE(D3D11_STENCIL_OP, StencilPassOp, D3D11_STENCIL_OP_REPLACE)
FRONT_DEPTH_STENCIL_DESCRIPTION_TEST_CASE(D3D11_COMPARISON_FUNC, StencilFunc, D3D11_COMPARISON_NEVER)

#define BACK_DEPTH_STENCIL_DESCRIPTION_TEST_CASE(type_, fieldName_, value_) \
	DEPTH_STENCIL_DESCRIPTION_FIXTURE_TEST_CASE(Back##fieldName_##_, type_, value_, BackFace.fieldName_)
BACK_DEPTH_STENCIL_DESCRIPTION_TEST_CASE(D3D11_STENCIL_OP, StencilFailOp, D3D11_STENCIL_OP_REPLACE)
BACK_DEPTH_STENCIL_DESCRIPTION_TEST_CASE(D3D11_STENCIL_OP, StencilDepthFailOp, D3D11_STENCIL_OP_REPLACE)
BACK_DEPTH_STENCIL_DESCRIPTION_TEST_CASE(D3D11_STENCIL_OP, StencilPassOp, D3D11_STENCIL_OP_REPLACE)
BACK_DEPTH_STENCIL_DESCRIPTION_TEST_CASE(D3D11_COMPARISON_FUNC, StencilFunc, D3D11_COMPARISON_NEVER)

BOOST_FIXTURE_TEST_CASE(Create, TestDepthStencilDescription)
{
	FakeD3D11Device device;
	FakeD3D11DepthStencilState state;
	device.CreateDepthStencilStateFakeResult = &state;
	device.CreateDepthStencilStateFakeHResult = S_OK;
	ID3D11DepthStencilState *result = m_desc.Create(&device);
	BOOST_REQUIRE(device.CreateDepthStencilStateCalled);
	BOOST_REQUIRE_EQUAL(&m_desc, device.CreateDepthStencilStateLastDesc);
	BOOST_REQUIRE_EQUAL(&state, result);
}

BOOST_AUTO_TEST_SUITE_END()
